package com.syni.mdd.yhd.common.all.controller.api.business;

import com.alibaba.fastjson.JSON;
import com.syni.mdd.sjb.common.component.utils.common.utils.BeanUtils;
import com.syni.mdd.sjb.common.component.utils.common.utils.DateTimeUtils;
import com.syni.mdd.sjb.common.component.utils.common.utils.ResultMapHelper;
import com.syni.mdd.sjb.common.component.utils.common.utils.RpcResponseVo;
import com.syni.mdd.yhd.common.all.constants.Constants;
import com.syni.mdd.yhd.common.all.constants.ResultCode;
import com.syni.mdd.yhd.common.all.constants.ResultMsg;
import com.syni.mdd.yhd.common.all.entity.BmsBusiness;
import com.syni.mdd.yhd.common.all.entity.BmsBusinessType;
import com.syni.mdd.yhd.common.all.entity.BmsDxGroupBuy;
import com.syni.mdd.yhd.common.all.entity.BmsUserBusinessAuth;
import com.syni.mdd.yhd.common.all.service.*;
import com.syni.mdd.yhd.common.all.utils.SpecificationUtils;
import com.syni.mdd.yhd.common.all.vo.rp.apiBusiness.GetBusinessEarningsRpVo;
import com.syni.mdd.yhd.common.all.vo.rp.apiBusiness.GetCanClaimBusinessVo;
import com.syni.mdd.sjb.common.component.utils.feign.dto.mddAll.apiBusiness.*;
import com.syni.mdd.sjb.common.component.utils.feign.service.mddAll.BusinessRestService;
import com.syni.mdd.sjb.common.component.utils.feign.service.mdd.sjb.common.datatreasure.DxshApiIndustryRestService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @className BusinessInfoRestApi
 * @description TOO
 * @Author cfx
 * @DATE 2020/4/6 22:14
 * @VERSION 1.0
 **/
@RestController
@RequestMapping("/apiBusiness")
@Log4j2
public class BusinessRestApi implements BusinessRestService{

    @Autowired
    BmsUserBusinessService bmsUserBusinessService;

    @Autowired
    BmsUserBusinessAuthService bmsUserBusinessAuthService;

    @Autowired
    BmsBusinessService bmsBusinessService;

    @Autowired
    BmsBusinessTypeRelationService bmsBusinessTypeRelationService;

    @Autowired
    BmsBusinessLabelService bmsBusinessLabelService;

    @Autowired
    BmsDxGroupBuyUseService bmsDxGroupBuyUseService;

    @Autowired
    BmsDxGroupBuyService bmsDxGroupBuyService;

    @Autowired
    BmsBusinessTypeService bmsBusinesseTypeService;

    @Autowired
    DxshApiIndustryRestService dxshApiIndustryRestService;

    @GetMapping("/getBusinessEarnings")
    public RpcResponseVo getBusinessEarnings(@RequestParam("userId") Integer userId) {
        GetBusinessEarningsRpVo getBusinessEarningsRpVo = new GetBusinessEarningsRpVo();
        List<BmsUserBusinessAuth> bmsUserBusinessAuths = bmsUserBusinessAuthService.findAllBusinessByUserId(userId);
        if(bmsUserBusinessAuths.size() > 0) {
            Date nowTime = new Date();
            String startTimes = DateTimeUtils.converDateToString(DateTimeUtils.getStartTimeOfDay(nowTime), DateTimeUtils.DATE_PATTERN_TIMESTAMP_03);
            String endTimes = DateTimeUtils.converDateToString(DateTimeUtils.getEndTimeOfDay(nowTime), DateTimeUtils.DATE_PATTERN_TIMESTAMP_03);
            Set<Integer> businessIds = bmsUserBusinessAuths.stream().map(BmsUserBusinessAuth::getBmsBusinessId).collect(Collectors.toSet());
            Double turnover = bmsUserBusinessService.getBusinessTodayEarByBusiness(businessIds,startTimes,endTimes);
            getBusinessEarningsRpVo.setTurnover(turnover);
            Integer verNum = bmsUserBusinessService.getBusinessTodayVerByBusiness(businessIds,startTimes,endTimes);
            getBusinessEarningsRpVo.setVerNum(verNum);
        }
        return RpcResponseVo.success(getBusinessEarningsRpVo,ResultMsg.MSG_GET_SUCCESS);
    }

    @GetMapping("/getCanClaimBusiness")
    public RpcResponseVo getCanClaimBusiness(@RequestParam("addrProvince") String addrProvince,
                                             @RequestParam("addrCity") String addrCity,
                                             @RequestParam("searchText") String searchText,
                                             @RequestParam(value = "typeName") String typeName,
                                             @RequestParam("pageNum") Integer pageNum,
                                             @RequestParam("pageSize") Integer pageSize) {
        Set<Integer> typeIds = bmsBusinesseTypeService.getBmsBusinessTypeByJsonName(typeName);
        List<BmsBusiness> bmsBusinesses = bmsBusinessService.getCanClaimBusiness(addrCity,searchText,typeIds,pageNum,pageSize);
        bmsBusinessTypeRelationService.postBmsBusinessTypeId(bmsBusinesses);
        Map<String,Object> userData = new HashMap<>();
        userData.put("count",bmsBusinessService.countCanClaimBusiness(addrCity,searchText,typeIds));
        userData.put("pageNum",pageNum);
        userData.put("pageSize",pageSize);
        List<GetCanClaimBusinessVo> getCanClaimBusinessVos = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(bmsBusinesses)){
            for(BmsBusiness bmsBusiness : bmsBusinesses){
                GetCanClaimBusinessVo getCanClaimBusinessVo = BeanUtils.copyProperties(bmsBusiness,GetCanClaimBusinessVo.class);
                getCanClaimBusinessVo.setTypeId(bmsBusiness.getTagsId());
                getCanClaimBusinessVos.add(getCanClaimBusinessVo);
            }
        }
        return RpcResponseVo.success(getCanClaimBusinessVos,userData,ResultMsg.MSG_GET_SUCCESS);
    }

    @Override
    @GetMapping("/getCanClaimBusinessNoTypeName")
    public RpcResponseVo getCanClaimBusinessNoTypeName(String addrProvince, String addrCity, String searchText, Integer pageNum, Integer pageSize) {
        List<BmsBusiness> bmsBusinesses = bmsBusinessService.getCanClaimBusiness(addrCity,searchText,pageNum,pageSize);
        bmsBusinessTypeRelationService.postBmsBusinessTypeId(bmsBusinesses);
        Map<String,Object> userData = new HashMap<>();
        userData.put("count",bmsBusinessService.countCanClaimBusiness(addrCity,searchText));
        userData.put("pageNum",pageNum);
        userData.put("pageSize",pageSize);
        List<GetCanClaimBusinessVo> getCanClaimBusinessVos = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(bmsBusinesses)){
            for(BmsBusiness bmsBusiness : bmsBusinesses){
                GetCanClaimBusinessVo getCanClaimBusinessVo = BeanUtils.copyProperties(bmsBusiness,GetCanClaimBusinessVo.class);
                getCanClaimBusinessVo.setTypeId(bmsBusiness.getTagsId());
                getCanClaimBusinessVos.add(getCanClaimBusinessVo);
            }
        }
        return RpcResponseVo.success(getCanClaimBusinessVos,userData,ResultMsg.MSG_GET_SUCCESS);
    }

    @PostMapping("/claimBusiness")
    public RpcResponseVo claimBusiness(ClaimBusinessDto claimBusinessDto){
        Map<String,Object> resultMap = bmsUserBusinessService.doClaimBusiness(claimBusinessDto.getUserId(),claimBusinessDto.getBusinessId(),
                null,null,claimBusinessDto.getInvitationCode());
        if(ResultMapHelper.isSuccess(resultMap)){
            Map<String,Object> data = (Map<String, Object>) resultMap.get("data");
            claimBusinessDto.setId(Integer.parseInt(data.get("id").toString()));
            claimBusinessDto.setBusinessId(((BmsBusiness)data.get("business")).getId());
            return RpcResponseVo.success(claimBusinessDto,ResultMsg.HAND_SUCCESS);
        }
        return RpcResponseVo.result(ResultCode.CODE_ERROR_100,resultMap.get("msg").toString());
    }

    @PostMapping("/claimBusiness/v2")
    public RpcResponseVo claimBusiness_v2(ClaimBusinessDto claimBusinessDto){
        Map<String,Object> resultMap = bmsUserBusinessService.doClaimBusiness_v2(claimBusinessDto.getUserId(),claimBusinessDto.getBusinessId(),claimBusinessDto.getInvitationCode(),claimBusinessDto.getBusinessAuthId());
        if(ResultMapHelper.isSuccess(resultMap)){
            Map<String,Object> data = (Map<String, Object>) resultMap.get("data");
            claimBusinessDto.setId(Integer.parseInt(data.get("id").toString()));
            claimBusinessDto.setBusinessId(((BmsBusiness)data.get("business")).getId());
            return RpcResponseVo.success(claimBusinessDto,ResultMsg.HAND_SUCCESS);
        }
        return RpcResponseVo.result(ResultCode.CODE_ERROR_100,resultMap.get("msg").toString());
    }

    @PostMapping("/certificationBusiness")
    public RpcResponseVo certificationBusiness(@RequestBody CertificationBusinessDto certificationBusinessDto){
        log.info("certificationBusinessDto:" + JSON.toJSONString(certificationBusinessDto));
        Map<String,Object> resultMap = bmsUserBusinessService.improveQualificationInfo(certificationBusinessDto);
        if(ResultMapHelper.isSuccess(resultMap)){
            BmsUserBusinessAuth bmsUserBusinessAuth = (BmsUserBusinessAuth)resultMap.get("data");
            certificationBusinessDto.setBusinessAuthId(bmsUserBusinessAuth.getId());
            certificationBusinessDto.setIsFinished(bmsUserBusinessAuth.getIsFinished());

            return RpcResponseVo.success(certificationBusinessDto,ResultMsg.HAND_SUCCESS);
        }
        return RpcResponseVo.result(ResultCode.CODE_ERROR_100,resultMap.get("msg").toString());
    }

    @PostMapping("/mddCertification")
    public RpcResponseVo mddCertification(@RequestBody CertificationBusinessDto certificationBusinessDto){
        log.info("certificationBusinessDto:" + JSON.toJSONString(certificationBusinessDto));
        Map<String,Object> resultMap = bmsUserBusinessService.mddQualificationInfo(certificationBusinessDto);
        if(ResultMapHelper.isSuccess(resultMap)){
            BmsUserBusinessAuth bmsUserBusinessAuth = (BmsUserBusinessAuth)resultMap.get("data");
            certificationBusinessDto.setBusinessAuthId(bmsUserBusinessAuth.getId());
            certificationBusinessDto.setIsFinished(bmsUserBusinessAuth.getIsFinished());
            if(bmsUserBusinessAuth.getBmsBusiness() != null) {
                certificationBusinessDto.setVendorName(bmsUserBusinessAuth.getBmsBusiness().getVendorName());
                certificationBusinessDto.setBusinessId(bmsUserBusinessAuth.getBmsBusiness().getId());
            }
            return RpcResponseVo.success(certificationBusinessDto,ResultMsg.HAND_SUCCESS);
        }
        return RpcResponseVo.result(ResultCode.CODE_ERROR_100,resultMap.get("msg").toString());
    }

    @GetMapping("/getUserClaimBusiness")
    public RpcResponseVo getUserClaimBusiness(@RequestParam("userId") Integer userId,@RequestParam("isSearchCert") Integer isSearchCert){
        Map<String,Object> conditionMap = new HashMap<>();
        conditionMap.put("bmsUserId",userId);
        if(isSearchCert == Constants.COMMON_FLAG_TRUE_INT){
            conditionMap.put("status",Constants.APPROVED_STATUS);
        }
        List<BmsUserBusinessAuth> bmsUserBusinessAuths = bmsUserBusinessAuthService.findAllUserBusiness(userId);
        List<BmsBusiness> bmsBusinesses = new ArrayList<>();
        for(BmsUserBusinessAuth bmsUserBusinessAuth : bmsUserBusinessAuths){
            if(bmsUserBusinessAuth.getBmsBusiness() != null){
                bmsBusinesses.add(bmsUserBusinessAuth.getBmsBusiness());
            }
        }
        bmsBusinessTypeRelationService.postBmsBusinessTypeId(bmsBusinesses);
        //组装数据
        List<GetUserClaimBusinessRpDto> getUserClaimBusinessRpDtos = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(bmsUserBusinessAuths)) {
            for(BmsUserBusinessAuth bu : bmsUserBusinessAuths){
                GetUserClaimBusinessRpDto getUserClaimBusinessRpDto = BeanUtils.copyProperties(bu, GetUserClaimBusinessRpDto.class);
                getUserClaimBusinessRpDto.setBusinessId(bu.getBmsBusinessId());
                if (bu.getBmsBusiness() != null) {
                    BeanUtils.copyProperties(bu.getBmsBusiness(), getUserClaimBusinessRpDto);
                    getUserClaimBusinessRpDto.setTypeId(bu.getBmsBusiness().getTagsId());
                    getUserClaimBusinessRpDto.setTypeName(bu.getBmsBusiness().getTags());
                    getUserClaimBusinessRpDto.setLabelName(bu.getBmsBusiness().getLabel());
                }
                getUserClaimBusinessRpDtos.add(getUserClaimBusinessRpDto);
            }
        }
        return RpcResponseVo.success(getUserClaimBusinessRpDtos,ResultMsg.MSG_GET_SUCCESS);
    }

    @PostMapping("/createBusiness")
    public RpcResponseVo createBusiness(@RequestBody CreateBusinessDto createBusinessDto){
        Map<String,Object> retMap = bmsBusinessService.createBusiness(createBusinessDto);
        if(ResultMapHelper.isSuccess(retMap)){
            BmsBusiness bmsBusiness = (BmsBusiness) retMap.get("data");
            createBusinessDto.setId(bmsBusiness.getId());
            return RpcResponseVo.success(createBusinessDto,ResultMsg.HAND_SUCCESS);
        }
        return RpcResponseVo.result(ResultCode.CODE_ERROR_100,retMap.get("msg").toString());
    }

    @PostMapping("/getBusinessById")
    public RpcResponseVo getBusinessById(@RequestBody GetBusinessDataByIdDto getBusinessDataByIdDto) {
        Optional<BmsBusiness> bmsBusinessOptional = bmsBusinessService.getBaseDao().findById(getBusinessDataByIdDto.getBusinessId());
        if(bmsBusinessOptional.isPresent()){
            BmsBusiness bmsBusiness = bmsBusinessOptional.get();
            bmsBusinessLabelService.postBusinessLabelId(bmsBusiness);
            getBusinessDataByIdDto = BeanUtils.copyProperties(bmsBusiness,GetBusinessDataByIdDto.class);
            return RpcResponseVo.success(getBusinessDataByIdDto,ResultMsg.MSG_GET_SUCCESS);
        }
        return RpcResponseVo.result(ResultCode.CODE_ERROR_100,"店铺不存在");
    }

    @PostMapping("/updateBusiness")
    public RpcResponseVo updateBusiness(@RequestBody UpdateBusinessDto updateBusinessDto) {
        Map<String,Object> ret = bmsBusinessService.updateBusiness(updateBusinessDto);
        if(ResultMapHelper.isSuccess(ret)) {
            updateBusinessDto = (UpdateBusinessDto) ret.get("data");
            return RpcResponseVo.success(updateBusinessDto, ResultMsg.HAND_SUCCESS);
        }
        return RpcResponseVo.result(ResultCode.CODE_ERROR_100, ret.get("msg").toString());
    }


    @PostMapping("/getMddBusinessDataByDxshApp")
    public RpcResponseVo getMddBusinessDataByDxshApp(@RequestBody GetMddBusinessDataByDxshAppDto getMddBusinessDataByDxshAppDto) {
        if(!(CollectionUtils.isNotEmpty(getMddBusinessDataByDxshAppDto.getBusinessIds()) && getMddBusinessDataByDxshAppDto.getBusinessIds().size() > 0)){
            return RpcResponseVo.result(ResultCode.CODE_ERROR_100,ResultMsg.CODE_PARAMS_MSG_FAIL);
        }
        Date nowTime = new Date();
        String startTimes  = DateTimeUtils.converDateToString(DateTimeUtils.getStartTimeOfDay(nowTime),DateTimeUtils.DATE_PATTERN_TIMESTAMP_03);
        String endTimes = DateTimeUtils.converDateToString(DateTimeUtils.getEndTimeOfDay(nowTime),DateTimeUtils.DATE_PATTERN_TIMESTAMP_03);
        Map<Integer,Integer> verMap = bmsDxGroupBuyUseService.countGroupBuyUseCountByBusinessIds(getMddBusinessDataByDxshAppDto.getBusinessIds(),startTimes,endTimes);
        Map<Integer,Integer> groupBuyMap = bmsDxGroupBuyService.countGroupBuyNumByBusinessIds(getMddBusinessDataByDxshAppDto.getBusinessIds());
        Map<Integer,BmsBusiness> bmsBusinessMap = bmsBusinessService.findBusinessByIdsIgnoreSetBuyCoupon(getMddBusinessDataByDxshAppDto.getBusinessIds());
        List<GetMddBusinessDataByDxshAppDto.BusinessDataDto> businessDataDtos = new ArrayList<>();
        getMddBusinessDataByDxshAppDto.getBusinessIds().forEach(businessId -> {
            GetMddBusinessDataByDxshAppDto.BusinessDataDto businessDataDto = new GetMddBusinessDataByDxshAppDto.BusinessDataDto();
            businessDataDto.setBusinessId(businessId);
            if(verMap.containsKey(businessId)){
                businessDataDto.setVerNum(verMap.get(businessId));
            }
            if(groupBuyMap.containsKey(businessId)){
                businessDataDto.setGroupBuyNum(groupBuyMap.get(businessId));
            }
            if(bmsBusinessMap.containsKey(businessId)){
                BmsBusiness bmsBusiness = bmsBusinessMap.get(businessId);
                businessDataDto.setVendorName(bmsBusiness.getVendorName());
                businessDataDto.setLoginUrl(bmsBusiness.getLogoUrl());
                businessDataDto.setAddrProvince(bmsBusiness.getAddrProvince());
                businessDataDto.setAddrCity(bmsBusiness.getAddrCity());
                businessDataDto.setAddrDistrict(bmsBusiness.getAddrDistrict());
                businessDataDto.setAddrDetails(bmsBusiness.getAddrDetails());
                businessDataDto.setLogoUrl(bmsBusiness.getLogoUrl());
            }

            businessDataDtos.add(businessDataDto);
        });
        getMddBusinessDataByDxshAppDto.setBusinessDatas(businessDataDtos);
        return RpcResponseVo.success(getMddBusinessDataByDxshAppDto,ResultMsg.MSG_GET_SUCCESS);
    }

    @GetMapping("/getBusinessAuthByBusinessId")
    public RpcResponseVo getBusinessAuthByBusinessId(@RequestParam("businessId") Integer businessId) {
        BmsUserBusinessAuth bmsUserBusinessAuth = bmsUserBusinessAuthService.findByBusinessIdNotReject(businessId);
        if(bmsUserBusinessAuth != null){
            BusinessAuthDto businessAuthDto = BeanUtils.copyProperties(bmsUserBusinessAuth,BusinessAuthDto.class);
            businessAuthDto.setBmsBusinessId(bmsUserBusinessAuth.getBmsBusinessId());
            return RpcResponseVo.success(businessAuthDto,ResultMsg.MSG_GET_SUCCESS);
        }
        return RpcResponseVo.result(ResultCode.CODE_ERROR_100,ResultMsg.CODE_BUSINESS_NO_EXIST);
    }

    @Override
    public RpcResponseVo getBusinessByIds(GetBusinessDataByIdsDto getBusinessDataByIdsDto) {
        List<BmsBusiness> bmsBusinesses = bmsBusinessService.getBaseDao().findByIdIn(getBusinessDataByIdsDto.getBusinessIds());
        if(CollectionUtils.isNotEmpty(bmsBusinesses)){
            bmsBusinessTypeRelationService.postBmsBusinessTypeId(bmsBusinesses);
            bmsBusinesses.forEach(bu -> {
                GetBusinessDataByIdDto getBusinessDataByIdDto = BeanUtils.copyProperties(bu,GetBusinessDataByIdDto.class);
                getBusinessDataByIdDto.setTypeId(bu.getTagsId());
                getBusinessDataByIdsDto.getBusinessData().add(getBusinessDataByIdDto);
            });
            return RpcResponseVo.success(getBusinessDataByIdsDto,ResultMsg.MSG_GET_SUCCESS);
        }
        return RpcResponseVo.result(ResultCode.CODE_ERROR_100,"店铺不存在");
    }

    @GetMapping("/getBusinessType")
    public Map<String,Object> getBusinessType() {
//        Map map = new LinkedHashMap();
//        Pageable pageable = PageRequest.of(0,10,dsc,);
//        Page<BmsBusinessType> page = bmsBusinesseTypeService.getBaseDao().findAll(new SpecificationUtils(map),pageable);
//        List<BmsBusinessType> bmsBusinessTypes = page.getContent();
//        List<BmsBusinessType> bmsBusinessTypes = bmsBusinesseTypeService.getBaseDao().findByIsDelete(Constants.COMMON_FLAG_FALSE_INT);
//        List<GetBusinessTypeDto> getBusinessTypeDtos = BeanUtils.copyList(bmsBusinessTypes,GetBusinessTypeDto.class);
//          Pageable pageable = PageRequest.of(0,10, Sort.Direction.DESC,"id","name");
//        List<Sort.Order> orders = new ArrayList<>();
//        orders.add( new Sort.Order(Sort.Direction.DESC, "it"));
//        orders.add( new Sort.Order(Sort.Direction.ASC, "NAME"));
//        Sort sort = new Sort(orders);
        List<GetBusinessTypeDto> getBusinessTypeDtos = new ArrayList<>();
        RpcResponseVo rpcResponseVo = dxshApiIndustryRestService.getAllIndustry();
        if(rpcResponseVo.isSuccess()){
            List<Map<String,Object>> data = (List<Map<String,Object>> ) rpcResponseVo.getData();
            if(CollectionUtils.isNotEmpty(data)){
                for(Map<String,Object> obj : data){
                    GetBusinessTypeDto getBusinessTypeDto = new GetBusinessTypeDto();
                    getBusinessTypeDto.setId(Integer.parseInt(obj.get("buId").toString()));
                    getBusinessTypeDto.setTypeName(obj.get("industryName").toString());
                    getBusinessTypeDtos.add(getBusinessTypeDto);
                }
            }
        }
        return ResultMapHelper.success(getBusinessTypeDtos,ResultMsg.MSG_GET_SUCCESS);
    }
}
